第2章 スレッドを扱う
OS における マルチプロセッシング
タスク管理 時に発生する コンテキストスイッチ のたびに オーバーヘッド が発生する
∵
OS は現在のプロセスの状態を保持し、後で中断したところから再開できるようにするため
また、OS は次に実行するプロセスの状態をロードする必要がある
プロセスコンテキストブロック(PCB)
タスク管理を始めとする OS の仕事は、シングルコアであってもマルチコアであってもそれほど違いはないが、スケジューラ が複数の CPU にプロセスをスケジューリングする必要がある 点は異なる
プロセス による 並行処理
OS の各プロセスは、他のプロセスから独立した メモリ空間 を持つ
そのため、あるプロセスが クラッシュ しても、他のプロセスに影響を及ぼさない
その代償として、多くのメモリを消費し、起動にも時間がかかる
プロセスの生成
OS はプロセスを生成、開始、終了する システムコール を提供している
Windows: CreateProcess
呼び出されると、プロセスの作成、資源の割り当て、コードのロードを経て、実行が開始される
UNIX: fork
呼び出されると、OS は レジスタ や スタック、ファイルハンドラ、プログラムカウンタ を含むメモリ空間と資源ハンドラの完全なコピーを作成(fork)する
そして、新しいプロセス(子プロセス)がその時点から処理を続ける
https://scrapbox.io/files/67aade1545c57e75921ae5fe.png
Copy on write によって最適化されている
fork は親プロセス(fork を呼び出したプロセス)では PID を返し、子プロセスでは 0 を返す
各プロセスでは、この fork の戻り値に基づいて実行する命令を決定する
子プロセスではコピーされた資源を使うこともできるが、更新したり、クリアして新しく開始することも可能
∵ プロセスは独立しており、親プロセスには影響を与えないため
各プロセスは独立した空間を持つため、新しいプロセスを生成するたびにメモリを消費する
また、資源のコピーや割り当てにも時間がかかるため、CPU サイクル を消費する
そのため、多くのプロセスを生成すると、システムに大きな負荷を与える
Go でのプロセス操作は syscall パッケージに限定されている
OS 依存
e.g.
Windows: CreateProcess() 調べたけど存在しない… Deprecated にもない…
UNIX: ForkExec() / StartProcess()
また、Exec() を用いると新しいプロセスでコマンドを実行できる
ただし、Go の並行プログラミングでは、重量なプロセスは使わず、軽量な スレッド や ゴルーチン を用いる